import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QScrollArea, QToolBox, QPushButton, QFrame, QFormLayout, \
    QLabel, QDoubleSpinBox, QComboBox, QSpinBox, QLineEdit, QMessageBox

from 自动化数据采集插件.config import FLOW_ITEM_S


def add_double_spinbox_widget(key, value):
    """
    添加一个double_spinbox
    :param key: 参数名
    :param value: 参数值
    :return:
    """
    label = QLabel(value['desc'])
    double_spinbox = QDoubleSpinBox()
    double_spinbox.setObjectName(key + '_doubleSpinbox')
    # 设置默认值
    if 'default' in value:
        double_spinbox.setValue(value['default'])
    # 设置最小宽度
    double_spinbox.setMinimumWidth(100)
    # 禁止滚轮调整
    double_spinbox.setWrapping(False)
    if 'now_value' in value:
        double_spinbox.setValue(value['now_value'])
    return label, double_spinbox


def add_input_widget(key, value):
    """
    添加一个输入框
    :param key: 参数名
    :param value: 参数值
    :return:
    """
    label = QLabel(value['desc'])
    input_ = QLineEdit()
    input_.setPlaceholderText('请输入' + value['desc'])
    input_.setObjectName(key + '_input')
    if 'now_value' in value:
        input_.setText(value['now_value'])
    return label, input_


def add_spinbox_widget(key, value):
    """
    添加一个spinbox
    :param key: 参数名
    :param value: 参数值
    :return:
    """
    label = QLabel(value['desc'])
    spinbox = QSpinBox()
    spinbox.setObjectName(key + '_spinbox')
    # 设置无上限最大值
    spinbox.setMaximum(999999)
    # 设置默认值
    if 'default' in value:
        spinbox.setValue(value['default'])
    # 设置最小宽度
    spinbox.setMinimumWidth(100)
    # 禁止滚轮调整
    spinbox.setWrapping(False)
    if 'now_value' in value:
        spinbox.setValue(value['now_value'])
    return label, spinbox


def add_combobox_widget(key, value):
    """
    添加一个下拉框
    :param key:  参数名
    :param value:  参数值
    :return: None
    """
    label = QLabel(value['desc'])
    combobox = QComboBox()
    combobox.setObjectName(key + '_combobox')
    combobox.addItems(value['options'])
    if 'now_value' in value:
        combobox.setCurrentText(value['now_value'])
    return label, combobox


def add_param_widget(key, value: dict, formLayout: QFormLayout):
    """
    添加参数组件,根据参数类型添加不同的组件
    :param key:  参数名
    :param value:  参数值,其中包含了参数的输入类型
    :param formLayout:  表单布局
    :return:
    """
    label = None
    ele = None
    if value['type'] == 'input':
        label, ele = add_input_widget(key, value)
    elif value['type'] == 'spinbox':
        label, ele = add_spinbox_widget(key, value)
    elif value['type'] == 'combobox':
        label, ele = add_combobox_widget(key, value)
    elif value['type'] == 'doubleSpinbox':
        label, ele = add_double_spinbox_widget(key, value)
    if label is not None and ele is not None:
        formLayout.addRow(label, ele)


class CommandWidget(QWidget):
    def __init__(self, flow_items: dict, parent=None):
        super().__init__()
        self.parent = parent
        self.type_with_items = {}
        for k, v in flow_items.items():
            if v['type'] not in self.type_with_items:
                self.type_with_items[v['type']] = {}
            self.type_with_items[v['type']][k] = v
        self.init_ui()

    def init_ui(self):
        """
        初始化UI
        :return:  None
        """
        mainLayout = QVBoxLayout(self)
        scrollArea = QScrollArea(self)
        scrollArea.setWidgetResizable(True)
        toolBox = QToolBox()
        for k, v in self.type_with_items.items():
            page = QWidget()
            pageLayout = QVBoxLayout(page)
            for k1, v1 in v.items():
                # 添加一个FORM布局
                formLayout = QFormLayout()
                formLayout.setObjectName(k1 + '_formLayout')
                # 元素靠左
                formLayout.setLabelAlignment(Qt.AlignLeft)
                # 添加 label 和 input
                for k2, v2 in v1.items():
                    if k2 == 'need_start_end' or k2 == 'type':
                        continue
                    add_param_widget(k2, v2, formLayout)

                btn = QPushButton(f"<< {k1}")
                formLayout.addRow(btn)
                btn.clicked.connect(self.insert_flow)

                pageLayout.addLayout(formLayout)
                # 添加一条横线
                line = QFrame()
                line.setFrameShape(QFrame.HLine)
                line.setFrameShadow(QFrame.Sunken)
                pageLayout.addWidget(line)
            pageLayout.addStretch(1)
            toolBox.addItem(page, f"{k}")
        scrollArea.setWidget(toolBox)
        mainLayout.addWidget(scrollArea)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(mainLayout)
        # 设置外边距为 0
        self.setContentsMargins(0, 0, 0, 0)

    def insert_flow(self):
        button = self.sender()
        form_layout = self.findFormLayout(button)
        if form_layout:
            print(f"Button '{button.text()}' is in the form layout, '{form_layout.objectName()}'")
            if self.parent is not None:
                flow_name = form_layout.objectName().replace('_formLayout', '')
                user_fill_params = self.parent.get_params_form(form_layout, flow_name)
                print(user_fill_params)
                self.parent.insert_flow(flow_name, user_fill_params)
        else:
            print(f"Form layout not found for button '{button.text()}'")

    def findFormLayout(self, widget):
        while widget is not None:
            parent = widget.parentWidget()
            if parent is None:
                break
            for layout in parent.findChildren(QFormLayout):
                if layout.indexOf(widget) != -1:
                    return layout
            widget = parent
        return None


if __name__ == '__main__':
    item_list = FLOW_ITEM_S
    app = QApplication(sys.argv)
    ex = CommandWidget(item_list)
    ex.setGeometry(300, 300, 600, 800)
    ex.setWindowTitle('指令控制面板')
    ex.show()
    sys.exit(app.exec_())
